package com.eveinfo.display.setting;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.eveinfo.R;
import com.eveinfo.tools.Logging;

public class SettingDownloadView extends Activity {

	private final Activity activity;
	
	public enum CheckFile {
		SAME_FILE, NO_FILE, NOT_SAME_FILE, FILE_EXIST;
	}

	public static final String SERVER_ADDRESS = "http://www.louisoz.net/eveinfo/";
	public static final String PICTURES_DB_NAME = "pictures.db";
	public static final String ITEMS_DB_NAME = "dominion.db";
	public static final String DATABASE_DST = "/sdcard/eveinfo/";

	private static final int DIALOG_DOWNLOAD_PREP = 0;
	private static final int DIALOG_DOWNLOAD = 1;
	// private static final int DIALOG_UNZIP = 1;

	private ProgressDialog progressDialog;
	private ImageView itemsIV;
	private ImageView picturesIV;
	private TextView info;

	private Have haveItems;
	private Have havePictures;

	private boolean isItemsChecked;
	private boolean isPicturesChecked;

	class Have {
		boolean have = false;
	}

	public SettingDownloadView() {
		activity = this;
		haveItems = new Have();
		havePictures = new Have();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.settingdownload);

		itemsIV = (ImageView) findViewById(R.id.IVSettingDownloadItems);
		picturesIV = (ImageView) findViewById(R.id.IVSettingDownloadPictures);

		TextView itemsTV = (TextView) findViewById(R.id.TVSettingDownloadItems);

		
//		AlertDialog.Builder builder1 = new AlertDialog.Builder(this);
//		builder1.setMessage(SERVER_ADDRESS + " unreachable, try later.")
//		       .setCancelable(false)
//		       .setNegativeButton("Ok", new DialogInterface.OnClickListener() {
//		           public void onClick(DialogInterface dialog, int id) {
//		                dialog.cancel();
//		                activity.finish();
//		           }
//		       });
//		AlertDialog alert1 = builder1.create();
//		
//		try {
//			InetAddress.getByName(SERVER_ADDRESS);
//		} catch (UnknownHostException e1) {
//			alert1.show();
//		}

		try {
			URL url;
			url = new URL(SERVER_ADDRESS + ITEMS_DB_NAME);
			URLConnection conn;
			conn = url.openConnection();
			int contentLength = conn.getContentLength();
			itemsTV.setText(ITEMS_DB_NAME + " (" + (contentLength / 1024 / 1000) + "MB)");
		} catch (IOException e) {
			Logging.getInstance().e(e);
			e.printStackTrace();
			itemsTV.setText(ITEMS_DB_NAME);
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("Can't reach " + SERVER_ADDRESS + ITEMS_DB_NAME
							+ " to check the file authenticity.");
			AlertDialog alert = builder.create();
			alert.show();
		}

		TextView picturesTV = (TextView) findViewById(R.id.TVSettingDownloadPictures);
		try {
			URL url;
			url = new URL(SERVER_ADDRESS + PICTURES_DB_NAME);
			URLConnection conn;
			conn = url.openConnection();
			int contentLength = conn.getContentLength();
			picturesTV.setText(PICTURES_DB_NAME + " (" + (contentLength / 1024 / 1000) + "MB)");
		} catch (IOException e) {
			Logging.getInstance().e(e);
			e.printStackTrace();
			picturesTV.setText(PICTURES_DB_NAME);
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("Can't reach " + SERVER_ADDRESS + PICTURES_DB_NAME
					+ " to check the file authenticity.");
			AlertDialog alert = builder.create();
			alert.show();
		}

		info = (TextView) findViewById(R.id.TVSettingDownloadInfo);

		checkAllFiles();

		Button dlButton = (Button) findViewById(R.id.BSettingDownloadDl);
		dlButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				showDialog(DIALOG_DOWNLOAD_PREP);
			}
		});

	}

	private void checkAllFiles() {
		if (checkFile(ITEMS_DB_NAME, this)) {
			itemsIV.setImageResource(R.drawable.green);
			haveItems.have = true;
		} else {
			itemsIV.setImageResource(R.drawable.red);
			haveItems.have = false;
		}
		if (checkFile(PICTURES_DB_NAME, this)) {
			picturesIV.setImageResource(R.drawable.green);
			havePictures.have = true;
		} else {
			picturesIV.setImageResource(R.drawable.red);
			havePictures.have = false;
		}
		if (!haveItems.have || !havePictures.have) {
			info.setText("You don't have the needed databases for all the application features.\n\n"
					+ "You can download them from the mobile phone by clicking to the Download Button or from:\n\n"
					+ SERVER_ADDRESS + ".\n\nThe Destination Folder should be:\n\n" + DATABASE_DST + ".");
		} else {
			info.setText("");
		}
	}

	public static CheckFile checkFile(String fileName) {
		File file = new File(DATABASE_DST + fileName);
		if (file.exists()) {
			URL url;
			try {
				url = new URL(SERVER_ADDRESS + fileName);
				URLConnection conn = url.openConnection();
				int contentLength = conn.getContentLength();
				if (contentLength != file.length()) {
					return CheckFile.NOT_SAME_FILE;
				}
			} catch (IOException e) {
				return CheckFile.FILE_EXIST;
			}
			return CheckFile.SAME_FILE;
		}
		return CheckFile.NO_FILE;
	}

	public static boolean checkFile(String fileName, Context context) {
		AlertDialog.Builder builder;
		AlertDialog alert;
		final CheckFile checkFile = checkFile(fileName);
		switch (checkFile) {
		case SAME_FILE:
			return true;
		case NO_FILE:
			return false;
		case NOT_SAME_FILE:
			builder = new AlertDialog.Builder(context);
			builder.setMessage("Not the same than " + SERVER_ADDRESS + fileName);
			alert = builder.create();
			alert.show();
			return false;
		case FILE_EXIST:
			builder = new AlertDialog.Builder(context);
			builder.setMessage("Can't reach the " + SERVER_ADDRESS + fileName + " to check the file authenticity.");
			alert = builder.create();
			alert.show();
			return false;
		}
		return false;
	}

	protected Dialog onCreateDialog(int id) {
		final Thread thread;
		switch (id) {
		case DIALOG_DOWNLOAD_PREP:
			final Dialog dialog = new Dialog(this);
			dialog.setTitle("Download");

			LinearLayout layout = new LinearLayout(this);
			layout.setOrientation(LinearLayout.VERTICAL);

			final CheckBox itemsCB = new CheckBox(this);
			itemsCB.setText(ITEMS_DB_NAME);
			if (!haveItems.have) {
				itemsCB.setChecked(true);
			}
			layout.addView(itemsCB);

			final CheckBox picturesCB = new CheckBox(this);
			picturesCB.setText(PICTURES_DB_NAME);
			if (!havePictures.have) {
				picturesCB.setChecked(true);
			}
			layout.addView(picturesCB);

			Button button = new Button(this);
			button.setText("Download");
			button.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					isItemsChecked = itemsCB.isChecked();
					isPicturesChecked = picturesCB.isChecked();
					dismissDialog(DIALOG_DOWNLOAD_PREP);
					if (!isItemsChecked && !isPicturesChecked)
						return;
					showDialog(DIALOG_DOWNLOAD);
				}
			});
			layout.addView(button);
			dialog.setContentView(layout);
			return dialog;
		case DIALOG_DOWNLOAD:
			try {
				final Handler handler;
				int total = 0;
				final URLConnection itemsConn;

				if (isItemsChecked) {
					URL itemsURL = new URL(SERVER_ADDRESS + ITEMS_DB_NAME);
					itemsConn = itemsURL.openConnection();
					total += itemsConn.getContentLength();
				} else {
					itemsConn = null;
				}

				final URLConnection picturesConn;
				if (isPicturesChecked) {
					URL pictureURL = new URL(SERVER_ADDRESS + PICTURES_DB_NAME);
					picturesConn = pictureURL.openConnection();
					total += picturesConn.getContentLength();
				} else {
					picturesConn = null;
				}

				handler = getHandler(total, DIALOG_DOWNLOAD);

				progressDialog = new ProgressDialog(this);
				progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
				progressDialog.setMax(total);
				progressDialog.setMessage("Downloading ...");
				progressDialog.setCancelable(true);
				thread = new Thread() {
					public void run() {
						int total = 0;
						if (isItemsChecked) {
							total = getDataBase(itemsConn, handler, ITEMS_DB_NAME, total);
						}
						if (isPicturesChecked) {
							total = getDataBase(picturesConn, handler, PICTURES_DB_NAME, total);
						}
					}
				};
				thread.start();
				progressDialog.setOnCancelListener(new OnCancelListener() {
					@Override
					public void onCancel(DialogInterface dialog) {
						thread.stop();
					}
				});
				return progressDialog;
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			break;
		default:
			return null;
		}
		return null;
	}

	private Handler getHandler(final int lenght, final int dialog) {
		Handler handler = new Handler() {
			public void handleMessage(Message msg) {
				int total = msg.getData().getInt("total");
				progressDialog.setProgress(total);
				if (total >= lenght) {
					dismissDialog(dialog);
					checkAllFiles();
				}
			}
		};
		return handler;
	}

	private int getDataBase(URLConnection conn, Handler mHandler, String fileName, int count) {
		int total = count;
		InputStream is = null;
		BufferedInputStream bis = null;
		FileOutputStream fos = null;
		new File(DATABASE_DST).mkdir();
		File file = new File(DATABASE_DST, fileName);
		try {
			conn.connect();
			is = conn.getInputStream();
			bis = new BufferedInputStream(is);
			fos = new FileOutputStream(file);
			BufferedOutputStream bos = new BufferedOutputStream(fos);

			int size = 512 * 1024;
			byte buffer[] = new byte[size];
			int nbLecture;
			while ((nbLecture = bis.read(buffer)) != -1) {
				total += nbLecture;
				Message msg = mHandler.obtainMessage();
				Bundle b = new Bundle();
				b.putInt("total", total);
				msg.setData(b);
				mHandler.sendMessage(msg);
				bos.write(buffer, 0, nbLecture);
			}
			bos.flush();
			bis.close();
			return total;
		} catch (IOException e) {
			Logging.getInstance().e(e);
			e.printStackTrace();
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return total;
	}
	// case DIALOG_UNZIP:
	// handler = new Handler() {
	// public void handleMessage(Message msg) {
	// int total = msg.getData().getInt("total");
	// progressDialog.setProgress(total);
	// if (total >= 10085376) {
	// dismissDialog(DIALOG_UNZIP);
	// }
	// }
	// };
	// progressDialog = new ProgressDialog(this);
	// progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
	// progressDialog.setMessage("Step 2/2 Unzip ...");
	// progressDialog.setMax(10085376);
	// thread = new Thread() {
	// public void run() {
	// Unzip.unzip(activity, handler, this);
	// }
	// };
	// thread.start();
	// return progressDialog;
}